package com.sinodata.bsm.center.web.action.resource;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;

import com.sinodata.bsm.center.bean.ResBean;
import com.sinodata.bsm.center.service.relation.ResRelationService;
import com.sinodata.bsm.center.service.resource.ResService;
import com.sinodata.bsm.center.util.web.Struts2Utils;
import com.sinodata.bsm.center.web.action.BaseAction;
import com.sinodata.bsm.common.vo.RelationType;
import com.sinodata.bsm.common.vo.Res;
import com.sinodata.bsm.common.vo.ResRelation;

/**
 * <p>
 * Description:
 * </p>
 * 
 * @author liulibo
 * @version 1.0
 * 
 * <p>
 * History:
 * 
 * Date Author Version Description
 * ---------------------------------------------------------------------------------
 * 2012-5-7 下午4:07:21 liulibo 1.0 To create
 * </p>
 * 
 * @since
 * @see
 */
public class ResRelationAction extends BaseAction<ResRelation> {
    private ResRelation entity;
    private Long id;
    private Long[] ids;
    @Autowired
    private ResService resService;
    @Autowired
    private ResRelationService resRelationService;

    @Override
    public String delete() throws Exception {
        ResRelation rel = resRelationService.getById(id);
        long startId = rel.getStartId().longValue();
        resRelationService.removeResRelation(rel);
        resRelationService.refreshResHealthStatus(startId);
        return null;
    }

    public String deleteByResId() throws Exception {
        String startId = request.getParameter("pId");
        String endId = request.getParameter("cId");
        resRelationService.removeResRelationByResId(Long.parseLong(startId), Long.parseLong(endId));
        return null;
    }

    /**
     * 更新资源关系标签
     * 
     * @return
     * @throws Exception
     */
    public String updateLabel() throws Exception {
        String label = request.getParameter("label");
        resRelationService.updateResRelationLabel(id, label);
        return null;
    }

    @Override
    public String input() throws Exception {
        Long parentId = Long.parseLong(Struts2Utils.getParameter("parentId"));
        Res res = resService.get(parentId);
        Struts2Utils.setRequestAttribute("res", res);
        return "input";
    }

    public String view() throws Exception {

        return "view";
    }

    @Override
    public String list() throws Exception {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    protected void prepareModel() throws Exception {
        if (id == null) {
            entity = new ResRelation();
        } else {
            entity = resRelationService.getById(id);
        }

    }

    @Override
    public String save() throws Exception {
        resRelationService.addResRelation(entity);
        resRelationService.refreshResHealthStatus(entity.getStartId());
        return null;
    }

    public String batchSave() {
        Long startId = Long.parseLong(Struts2Utils.getParameter("startId"));
        String[] resId = Struts2Utils.getParameter("resId").split(","); // 例：101,123,124
        Long relTypeId = Long.parseLong(Struts2Utils.getParameter("resRelId"));
        String label = Struts2Utils.getParameter("label");
        JSONObject object = new JSONObject();
        object.element("check", "true");
        List<Long> currentParentsId = resService.findParentIdsByResId(startId); // 当前资源的父资源
        ResBean[] currentChilds = ResBean.get(startId).children(); // 当前资源的子资源
        List<String> childs = Arrays.asList(resId);
        // 筛选父资源(父资源不能被被添加关系)
        for (int i = 0; i < currentParentsId.size(); i++) {
            String parentId = Long.toString(currentParentsId.get(i).longValue());
            if (childs.contains(parentId)) {
                Res res = resService.get(Long.parseLong(parentId));
                object.element("check", "false");
                object.element("checkInfo", res.getName() + "已经与当前资源建立父子关系");
                break;
            }
        }

        // 筛选儿子资源不能再次添加关系
        for (int i = 0; i < currentChilds.length; i++) {
            Res res = currentChilds[i].res();

            if (childs.contains(res.getId().toString())) {
                object.element("check", "false");
                object.element("checkInfo", res.getName() + "已经与当前资源建立父子关系");
                break;
            }
        }

        if (object.get("check").equals("true")) {

            for (int i = 0; i < resId.length; i++) {
                Long childId = Long.parseLong(resId[i]);
                ResRelation relation = new ResRelation();
                relation.setLabel(label);
                relation.setEndId(childId);
                relation.setStartId(startId);
                relation.setRelationTypeId(relTypeId);
                resRelationService.addResRelation(relation);
                resRelationService.refreshResHealthStatus(relation.getStartId());

                object.element("resRelationId", relation.getId());
            }

        }

        Struts2Utils.renderText(object.toString());
        return null;
    }

    private JSONObject makeChildren(Map<Long, List<RelationType>> map, RelationType parent) {
        Long pId = parent.getId();
        List<RelationType> ctypes = map.get(pId);
        JSONObject json = new JSONObject();
        json.element("id", pId);
        json.element("name", parent.getName());
        json.element("parentId", parent.getParent());
        JSONArray jsonArray = new JSONArray();
        if (ctypes != null && ctypes.size() > 0) {
            for (RelationType t : ctypes) {
                jsonArray.add(makeChildren(map, t));
            }
        }
        json.element("open", true);
        json.element("children", jsonArray);
        return json;
    }

    public String findResRelation() throws Exception {
        try {
            String resId = request.getParameter("resId");
            List<ResRelation> relList = resRelationService.getResRelationsOfRes(Long.parseLong(resId));
            JSONObject json = new JSONObject();
            Res res = resService.get(Long.parseLong(resId));
            json.element("startRes", res);
            JSONArray jsonArray = new JSONArray();
            if (relList != null) {
                for (ResRelation rel : relList) {
                    Long childResId = null;
                    // 查询子资源
                    if (rel.getStartId() == Long.parseLong(resId)) {
                        childResId = rel.getEndId();
                    }

                    // 查询父资源
                    else if (rel.getEndId() == Long.parseLong(resId)) {
                        childResId = rel.getStartId();
                    }

                    Res cRes = resService.get(childResId.longValue());
                    if (cRes == null) {
                        continue;
                    }
                    JSONObject cjson = new JSONObject();
                    cjson.element("res", cRes);
                    RelationType type = resRelationService.findRelationTypeById(rel.getRelationTypeId());
                    cjson.element("relType", type);
                    cjson.element("relation", rel);
                    jsonArray.add(cjson);
                }
            }
            json.element("children", jsonArray);
            Struts2Utils.renderText(json.toString());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public String typeTree() throws Exception {
        Set<RelationType> typeList = resRelationService.getSelfAndSubRelationType();
        RelationType[] types = typeList.toArray(new RelationType[typeList.size()]);
        Arrays.sort(types);

        Map<Long, List<RelationType>> map = new LinkedHashMap<Long, List<RelationType>>();
        List<RelationType> roots = new ArrayList<RelationType>();
        for (RelationType t : types) {
            List<RelationType> list = null;
            if (t.getParent() == null) {
                roots.add(t);
            }
            if (!map.containsKey(t.getId().longValue())) {
                list = new ArrayList<RelationType>();
                map.put(t.getId(), list);
            }
            if (t.getParent() != null) {
                map.get(t.getParent().longValue()).add(t);
            }
        }
        JSONArray jsonArray = new JSONArray();
        for (RelationType t : roots) {
            jsonArray.add(makeChildren(map, t));
        }
        Struts2Utils.renderText(jsonArray.toString());
        return null;
    }

    @Override
    public ResRelation getModel() {
        return entity;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long[] getIds() {
        return ids;
    }

    public void setIds(Long[] ids) {
        this.ids = ids;
    }

}
